export default class Overlay {
  on (eventType, callback) {
    if (!this.overlay) {
      console.error('对象未正确初始化')
      return
    }

    const handlerOfType = this.sandbox.eventMap.get(eventType)
    if (handlerOfType) {
      if (!handlerOfType.has(this.overlay)) {
        handlerOfType.set(this.overlay, new Set())
      }
      const callbackMap = handlerOfType.get(this.overlay)
      callbackMap.add(callback)
    } else {
      console.error('事件类型错误')
    }
  }

  off (eventType, callback) {
    if (eventType) {
      const handlerOfType = this.sandbox.eventMap.get(eventType)
      if (handlerOfType) {
        if (callback) {
          const callbackMap = handlerOfType.get(this.overlay)
          if (callbackMap) {
            if (callbackMap.has(callback)) {
              callbackMap.delete(callback)
            } else {
              console.error('不存在要销毁的函数')
            }
            if (!callbackMap.size) {
              handlerOfType.delete(this.overlay)
            }
          } else {
            console.error('事件类型中不存在该对象')
          }
        } else {
          handlerOfType.delete(this.overlay)
        }
      } else {
        console.error('事件类型有误')
      }
    } else {
      this.sandbox.eventMap.forEach(handlerOfType => {
        handlerOfType.delete(this.overlay)
      })
    }
  }

  destroy () {
    if (!this.overlay) return
    // 如果子对象有dispose方法（如Mesh、BufferGeometry等），调用它来释放资源
    if (this.animationId) {
      this.stopAnimation()
    }
    if (this.overlay.geometry) {
      this.overlay.geometry.dispose()
    }
    if (this.mark) {
      this.destroyMark()
    }

    if (this.overlay.material) {
      // 如果材质是一个数组（如Mesh有多个材质），遍历并调用dispose方法
      if (Array.isArray(this.overlay.material)) {
        this.overlay.material.forEach(m => m.dispose())
      } else {
        this.overlay.material.dispose()
      }
    }
    window.sandbox.scene.remove(this.overlay)
  }

  get visible () {
    return this.overlay.visible
  }

  set visible (value) {
    this.overlay.visible = value
  }

  updateModelMatrix () {
    const { x, y, z } = this._position
    this.overlay.position.set(x, y, z)
    const heading = this._rotation.x
    const pitch = this._rotation.y
    const roll = this._rotation.z
    this.overlay.rotation.set(
      GC.MathUtils.degToRad(heading), // 将度转换为弧度
      GC.MathUtils.degToRad(pitch),
      GC.MathUtils.degToRad(roll)
    )
    let scaleArr = [1, 1, 1]
    if (typeof this._scale === 'object') {
      scaleArr = [this._scale.x, this._scale.y, this._scale.z]
    } else {
      scaleArr = Array.isArray(this._scale) ? this._scale : [this._scale, this._scale, this._scale]
    }
    this.overlay.scale.set(...scaleArr)
  }

  get heading () {
    // return GC.MathUtils.radToDeg(this._rotation.y)
    return this._rotation.y
  }

  set heading (value) {
    this._rotation.y = value
    this.updateModelMatrix()
  }

  get pitch () {
    return this._rotation.x
    // return GC.MathUtils.radToDeg(this._rotation.x)
  }

  set pitch (value) {
    this._rotation.x = value
    this.updateModelMatrix()
  }

  get roll () {
    return this._rotation.z
    // return GC.MathUtils.radToDeg(this._rotation.z)
  }

  set roll (value) {
    this._rotation.z = value
    this.updateModelMatrix()
  }

  get scale () {
    return this._scale
  }

  set scale (value) {
    this._scale = value
    this.updateModelMatrix()
  }

  get position () {
    return this._position
  }

  set position (value) {
    const { x, y, z } = value
    this._position = {
      x: isNaN(x) ? this._position.x : x,
      z: isNaN(z) ? this._position.z : z,
      y: isNaN(y) ? this._position.y : y
    }
    this.updateModelMatrix()
  }
}
